package com.neo.tiny.admin.controller.auth;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.neo.tiny.admin.dto.user.UserInfoDTO;
import com.neo.tiny.admin.params.auth.AdminLoginParam;
import com.neo.tiny.admin.params.auth.AdminLoginSendSmsParam;
import com.neo.tiny.admin.params.auth.AdminSmsLoginParam;
import com.neo.tiny.admin.service.sys.impl.SysAuthService;
import com.neo.tiny.admin.vo.user.LoginResVO;
import com.neo.tiny.admin.vo.user.UserInfoVO;
import com.neo.tiny.common.common.ResResult;
import com.neo.tiny.common.constant.CacheConstants;
import com.neo.tiny.common.constant.ErrorCodeConstants;
import com.neo.tiny.common.exception.WebApiException;
import com.neo.tiny.common.util.SimpleCaptcha;
import com.neo.tiny.secrity.model.AdminUserDetails;
import com.neo.tiny.secrity.util.SecurityUtils;
import com.neo.tiny.service.RedisService;
import com.neo.tiny.token.store.OAuth2AccessToken;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description: 后台用户管理
 * @Author: yqz
 * @CreateDate: 2022/8/7 14:03
 */
@Api(tags = "后台用户管理")
@Slf4j
@RestController
@RequestMapping("/admin/auth")
public class AuthController {

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @Autowired
    private SysAuthService authService;

    @Autowired
    private RedisService redisService;

    @ApiOperation("生成验证码")
    @GetMapping("/createCaptcha")
    public void createCaptcha(HttpServletResponse response, String uuid) {
        //定义图形验证码的长、宽、验证码字符数、干扰元素个数
        SimpleCaptcha simpleCaptcha = new SimpleCaptcha(200, 50, 4, 20);
        try {
            simpleCaptcha.write(response.getOutputStream());
            redisService.set(CacheConstants.LOGIN_IMAGE_CODE + StrUtil.COLON + uuid, simpleCaptcha.getCode(), 300, TimeUnit.SECONDS);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("用户账户密码登录")
    @PostMapping("/login")
    public ResResult<LoginResVO> login(@Valid @RequestBody AdminLoginParam loginParam, HttpServletRequest request) {
        log.info("用户登录入参：{}", loginParam);
        checkCaptcha(loginParam);
        OAuth2AccessToken oAuth2AccessToken = authService.usernameLogin(loginParam.getUsername(), loginParam.getPassword(), request);

        return ResResult.success(BeanUtil.copyProperties(oAuth2AccessToken, LoginResVO.class));
    }


    @ApiOperation("用户手机号验证码登录")
    @PostMapping("/smsLogin")
    public ResResult<LoginResVO> smsLogin(@Valid @RequestBody AdminSmsLoginParam param, HttpServletRequest request) {
        log.info("用户手机号验证码登录入参：{}", param);
        OAuth2AccessToken oAuth2AccessToken = authService.smsLogin(param.getPhone(), param.getCode(), request);
        return ResResult.success(BeanUtil.copyProperties(oAuth2AccessToken, LoginResVO.class));
    }


    @ApiOperation("发送短信验证码")
    @PostMapping("/sendLoginSmsCode")
    public ResResult<String> sendLoginSmsCode(@Valid @RequestBody AdminLoginSendSmsParam param) {

        String code = authService.sendLoginSmsCode(param.getPhone());
        return ResResult.success(code);
    }

    public void checkCaptcha(AdminLoginParam loginParam) {

        Object captcha = redisService.get(CacheConstants.LOGIN_IMAGE_CODE + StrUtil.COLON + loginParam.getUuid());

        if (Objects.isNull(captcha)) {
            throw new WebApiException(ErrorCodeConstants.LOGIN_LOGIN_ERROR);
        }
        String captchaCode = captcha.toString();
        if (!StrUtil.equalsAnyIgnoreCase(captchaCode, loginParam.getCaptcha())) {
            throw new WebApiException(ErrorCodeConstants.LOGIN_LOGIN_ERROR);
        }
    }


    @ApiOperation("退出登录")
    @DeleteMapping("/logout")
    public ResResult<Boolean> logout(HttpServletRequest request) {
        authService.logout(request);
        return ResResult.success(true);
    }
}
